#include "reconstruction_service.h"
#include <iostream>
#include <chrono>
#include <thread>

ReconstructionService::ReconstructionService(const std::string& video_server_url)
    : video_server_url_(video_server_url) {
    
    network_client_ = std::make_unique<NetworkClient>(video_server_url);
    frame_processor_ = std::make_unique<FrameProcessor>();
    
    stats_.start_time = std::chrono::steady_clock::now();
}

ReconstructionService::~ReconstructionService() {
    stop_processing();
}

bool ReconstructionService::start_processing() {
    if (processing_flag.load()) {
        std::cout << "Processing is already running" << std::endl;
        return false;
    }
    
    // 启动视频流
    if (!start_video_stream()) {
        std::cout << "Failed to start video stream" << std::endl;
        return false;
    }
    
    // 重置统计信息
    stats_.frames_processed = 0;
    stats_.start_time = std::chrono::steady_clock::now();
    stats_.current_fps = 0.0;
    
    // 启动处理线程
    processing_flag.store(true);
    processing_thread_ = std::thread(&ReconstructionService::processing_loop, this);
    
    std::cout << "Reconstruction processing started" << std::endl;
    return true;
}

void ReconstructionService::stop_processing() {
    if (!processing_flag.load()) {
        return;
    }
    
    processing_flag.store(false);
    
    if (processing_thread_.joinable()) {
        processing_thread_.join();
    }
    
    std::cout << "Reconstruction processing stopped" << std::endl;
}

void ReconstructionService::processing_loop() {
    const int target_fps = 30;
    const auto frame_interval = std::chrono::microseconds(1000000 / target_fps);
    
    while (processing_flag.load()) {
        auto frame_start = std::chrono::steady_clock::now();
        
        // 获取当前帧
        auto frame_response = network_client_->get_current_frame();
        if (frame_response.success) {
            // 处理帧
            auto result = frame_processor_->process_frame(frame_response.frame);
            
            // 创建帧数据
            auto frame_data = std::make_shared<FrameData>();
            frame_data->original_frame = frame_response.frame.clone();
            frame_data->processed_frame = result.processed_frame.clone();
            frame_data->timestamp = frame_response.timestamp;
            frame_data->contours_count = result.contours_count;
            
            // 添加到缓冲区
            {
                std::lock_guard<std::mutex> lock(buffer_mutex_);
                frame_buffer_.push_back(frame_data);
                
                // 限制缓冲区大小
                if (frame_buffer_.size() > max_buffer_size) {
                    frame_buffer_.erase(frame_buffer_.begin());
                }
            }
            
            // 更新统计信息
            stats_.frames_processed++;
            update_stats();
            
            // 输出处理信息
            if (stats_.frames_processed % 30 == 0) {  // 每30帧输出一次
                std::cout << "Processed " << stats_.frames_processed 
                          << " frames, FPS: " << stats_.current_fps.load() 
                          << ", Processing time: " << result.processing_time_ms << "ms" << std::endl;
            }
        } else {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        
        // 控制帧率
        auto frame_end = std::chrono::steady_clock::now();
        auto elapsed = frame_end - frame_start;
        if (elapsed < frame_interval) {
            std::this_thread::sleep_for(frame_interval - elapsed);
        }
    }
}

void ReconstructionService::update_stats() {
    auto now = std::chrono::steady_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - stats_.start_time);
    
    if (elapsed.count() > 0) {
        double fps = static_cast<double>(stats_.frames_processed.load()) / elapsed.count();
        stats_.current_fps.store(fps);
    }
}

std::shared_ptr<FrameData> ReconstructionService::get_latest_frame() {
    std::lock_guard<std::mutex> lock(buffer_mutex_);
    
    if (frame_buffer_.empty()) {
        return nullptr;
    }
    
    return frame_buffer_.back();
}

ProcessingStats ReconstructionService::get_processing_stats() const {
    return stats_;
}

bool ReconstructionService::check_video_server_status() {
    return network_client_->is_connected();
}

bool ReconstructionService::start_video_stream() {
    return network_client_->start_video_stream();
} 